import 'dart:convert';
import 'dart:io';
import 'package:path/path.dart' as path;
import 'package:path_provider/path_provider.dart';
import 'package:intl/intl.dart';
import 'package:sqflite/sqflite.dart';

/// 文件服务类，统一处理应用中的文件操作
class FileServe {
  // ==================== 常量定义 ====================
  static const String _packageName = 'com.example.patchouli_knowledge';
  static const String _userConfig = 'config/user_config.json';
  static const String _appDataDirName = 'patchouli_knowledge';
  static const String _permissionTestFileName = '_permission_test.txt';
  static const String _memoryDbFileName = 'memory.tina';
  static const String _userGuideFileName = '知拾食用指南.md';
  static const String _userInfoFileName = 'user_info.json';
  static const String _appConfigFileName = 'app_config.json';
  static const String _docIndexFileName = 'index.json';
  static const String _docIdMappingsFileName = 'doc_id_mappings.json';
  static const String _difyDatasetConfigName = 'dify_dataset.json';
  static const String _llmConfigFileName = 'LLM.json';
  static const String _vivoOcrConfigFileName = 'vivo_ocr.json';
  static const String _tagFileName = 'tag.json';
  static const String _readingPositionsFileName = 'reading_positions.json';
  static const String _messagesPoolFileName = 'messages_pool.json';
  static const String _userPicPrefix = 'user_pic';
  
  // 子目录名称
  static const List<String> _subDirectories = [
    'docs', 'doc', 'chat', 'config', 'temp', 'data', 'notes'
  ];
  

  // ==================== 单例模式 ====================
  static final FileServe _instance = FileServe._internal();
  factory FileServe() => _instance;
  FileServe._internal();

  // ==================== 私有变量 ====================
  late String _appDataDir;
  bool _initialized = false;

  /// 当有新消息写入消息池时触发（由AgentManager在初始化时注入）
  static Future<void> Function()? onMessageShared;

  /// 当有新文档添加到知识库时触发（由AgentManager在初始化时注入）
  /// 形参：docId（可能为临时ID）、title、contentSnippet（尽力读取，可能为空）
  static Future<void> Function(String docId, String title, String contentSnippet)? onDocumentAdded;

  // ==================== 公共属性 ====================
  String get appDataDir => _appDataDir;

  // ==================== 初始化方法 ====================
  
  /// 初始化文件服务
  Future<void> initialize() async {
    if (_initialized) return;
    
    try {
      await _setupAppDataDirectory();
      await _testWritePermission();
      await _createSubDirectories();
      await _ensureUserGuideExists();
      await _initializeMemoryDatabase();
      _initialized = true;
    } catch (e) {
      rethrow;
    }
  }

  /// 初始化方法的别名，兼容main.dart中的调用
  Future<void> init() async => await initialize();

  // ==================== 私有辅助方法 ====================
  
  /// 设置应用数据目录
  Future<void> _setupAppDataDirectory() async {
    if (Platform.isAndroid) {
      try {
        final externalDir = await getExternalStorageDirectory();
        if (externalDir != null) {
          final androidDataPath = externalDir.path;
          final appDirIndex = androidDataPath.indexOf('/Android/data/');
          
          if (appDirIndex != -1) {
            final dataBasePath = androidDataPath.substring(0, appDirIndex + 14);
            final appDir = Directory(path.join(dataBasePath, _packageName));
            
            if (!await appDir.exists()) {
              await appDir.create(recursive: true);
            }
            
            _appDataDir = appDir.path;
            return;
          }
        }
      } catch (e) {
        // 继续执行回退逻辑
      }
    }
    
    await _fallbackToDocumentsDirectory();
  }

  /// 回退到使用应用文档目录
  Future<void> _fallbackToDocumentsDirectory() async {
    Directory? appDir;
    
    try {
      appDir = await getApplicationDocumentsDirectory();
    } catch (e) {
      appDir = await getTemporaryDirectory();
    }
    
    _appDataDir = path.join(appDir.path, _appDataDirName);
    
    final baseDir = Directory(_appDataDir);
    if (!await baseDir.exists()) {
      await baseDir.create(recursive: true);
    }
  }

  /// 测试写入权限
  Future<void> _testWritePermission() async {
    try {
      final testFile = File(path.join(_appDataDir, _permissionTestFileName));
      await testFile.writeAsString('测试写入 - ${DateTime.now()}');
      await testFile.readAsString();
      await testFile.delete();
    } catch (e) {
      // 权限测试失败，但不抛出异常
    }
  }

  /// 创建必要的子目录
  Future<void> _createSubDirectories() async {
    for (final dir in _subDirectories) {
      final directory = Directory(path.join(_appDataDir, dir));
      if (!await directory.exists()) {
        await directory.create(recursive: true);
      }
    }
  }

  /// 确保知拾食用指南.md文件存在
  Future<void> _ensureUserGuideExists() async {
    try {
      final docDir = Directory(path.join(_appDataDir, 'doc'));
      final aboutFile = File(path.join(docDir.path, _userGuideFileName));
      
      if (!await aboutFile.exists()) {
        await aboutFile.writeAsString(_getDefaultUserGuideContent());
      }
    } catch (e) {
      // 创建用户指南失败，但不影响应用启动
    }
  }

  /// 获取默认用户指南内容
  String _getDefaultUserGuideContent() {
    return '''
# 知拾使用指南

## ✨ 欢迎使用知拾！

**知拾**是一款由 AI 驱动的知识收集与管理软件，它将文档、图片、截图、拍照内容一键转化为你专属的知识库，并通过大模型提供个性化建议与智能问答。

无论是随手记录、拍照采集，还是跨软件快速导入，知拾都能为你高效整理、分类并构建你自己的专属知识库。

---

## 🚀 快速开始

### 如何添加知识？

1. 点击主页右下角 **「+」** 按钮，选择上传文档或图片；
2. 支持文档格式包括：`.docx`、`.txt`、`.md`、`.pdf`；
3. 直接上传截图或拍照，系统将通过 OCR 自动提取文字内容；
4. 传送门功能支持你在任何软件中长按选中内容并一键导入（在设置中开启）。

### 如何提问与对话？

* 下滑找到聊天入口点击即可进去；
* 支持自然语言输入，大模型将自动从你的知识库中检索相关内容，减少幻觉，更加可信；
* 你也可以直接在主页顶部搜索框中输入关键词，主动查询知识。

---

## 🧠 主要功能

### 📚 知识管理

* **文档上传**：支持多种格式的文件，包括文本、图片、扫描件等；
* **传送门导入**：长按选中文字或截图，一键导入为知识条目；
* **自动分类**：AI 自动判断归类，必要时创建新分类；
* **卡片式展示**：文档以卡片形式展现，点击即可预览或查看全文；
* **知识图谱**：自动分析文档间关系，构建你的知识网络。

### 🤖 智能 AI

* **上下文感知对话**：模型记住你的身份、兴趣、历史偏好；
* **个性化建议**：进入软件或切换页面时，大模型主动提供知识推荐；
* **语义理解与检索**：通过大模型理解提问语义，减少幻觉，准确检索；
* **文档命名与标签建议**：自动分析文档前2000字，生成标题与关键词标签。

---

## ⚙️ 技术与框架

| 模块       | 技术说明                       |
| -------- | -------------------------- |
| 软件框架     | Flutter：跨平台开发              |
| 知识库功能    | Dify：知识库构建、检索、上传           |
| OCR 支持   | vivo OCR：识别图片和拍照中的文字       |
| 大模型能力    | Qwen、BlueLM：多模型协同优化对话与内容理解 |
| Agent 框架 | tina-dart：统一管理大模型调用与工具整合   |

---

## 🎯 使用小技巧

* **建议开启传送门功能**：可在设置中打开，支持跨 App 快速导入知识；
* **命名技巧**：你可以手动编辑文档名，也可使用大模型生成的标题；
* **个性化身份设置**：在设置中添加标签或描述，帮助大模型更理解你；
* **对话历史保存**：系统会保存你的聊天记录，方便下次继续或回顾；
* **定期整理知识库**：使用卡片分类功能，让你的知识更有条理。
''';
  }

  /// 初始化记忆数据库
  Future<void> _initializeMemoryDatabase() async {
    try {
      final chatDir = Directory(path.join(_appDataDir, 'chat'));
      if (!await chatDir.exists()) {
        await chatDir.create(recursive: true);
      }
      
      final memoryDbPath = path.join(chatDir.path, _memoryDbFileName);
      
      final db = await openDatabase(
        memoryDbPath,
        version: 1,
        onCreate: (Database db, int version) async {
          await db.execute('''
            CREATE TABLE logs (
              id INTEGER PRIMARY KEY AUTOINCREMENT,
              time TEXT NOT NULL,
              content TEXT NOT NULL
            )
          ''');
        },
      );
      
      await db.close();
    } catch (e) {
      // 数据库初始化失败，但不影响应用启动
    }
  }

  /// 获取记忆数据库路径
  String getMemoryDatabasePath() {
    return path.join(_appDataDir, 'chat', _memoryDbFileName);
  }

  // ==================== 用户信息管理 ====================

  /// 保存用户信息
  Future<bool> saveUserInfo(Map<String, dynamic> userInfo) async {
    return await _saveJsonFile('config', _userInfoFileName, userInfo);
  }

  /// 读取用户信息
  Future<Map<String, dynamic>?> readUserInfo() async {
    return await _readJsonFile('config', _userInfoFileName);
  }

  /// 获取用户信息的别名方法，与readUserInfo保持一致
  Future<Map<String, dynamic>?> getUserInfo() async {
    return await readUserInfo();
  }

  // ==================== 聊天历史管理 ====================

  /// 保存聊天历史
  Future<bool> saveChatHistory(Map<String, dynamic> chatData, {String? date}) async {
    final today = date ?? DateFormat('yyyy-MM-dd').format(DateTime.now());
    return await _saveJsonFile('chat', '$today.json', chatData);
  }

  /// 读取聊天历史
  Future<Map<String, dynamic>?> readChatHistory({String? date}) async {
    final chatDate = date ?? DateFormat('yyyy-MM-dd').format(DateTime.now());
    return await _readJsonFile('chat', '$chatDate.json');
  }

  /// 列出所有聊天历史文件
  Future<List<String>> listChatHistoryFiles() async {
    try {
      if (!_initialized) await initialize();
      
      final chatDir = Directory(path.join(_appDataDir, 'chat'));
      if (!await chatDir.exists()) return [];
      
      final files = await chatDir
          .list()
          .where((entity) => entity is File && entity.path.endsWith('.json'))
          .map((entity) => entity.path)
          .toList();
      
      files.sort((a, b) => b.compareTo(a));
      return files;
    } catch (e) {
      return [];
    }
  }

  // ==================== 应用配置管理 ====================

  /// 保存应用配置
  Future<bool> saveAppConfig(Map<String, dynamic> config) async {
    return await _saveJsonFile('config', _appConfigFileName, config);
  }

  /// 读取应用配置
  Future<Map<String, dynamic>?> readAppConfig() async {
    return await _readJsonFile('config', _appConfigFileName);
  }

  /// 获取指定类型的配置
  Future<Map<String, dynamic>> getConfig(String configType) async {
    try {
      if (!_initialized) await initialize();
      
      final (fileName, defaultConfig) = _getConfigFileNameAndDefault(configType);
      final configFile = File(path.join(_appDataDir, 'config', fileName));
      
      if (await configFile.exists()) {
        final content = await configFile.readAsString();
        return jsonDecode(content);
      } else {
        await _ensureConfigDirectoryExists();
        await configFile.writeAsString(jsonEncode(defaultConfig));
        return defaultConfig;
      }
    } catch (e) {
      return {};
    }
  }

  /// 获取配置文件名和默认配置
  (String, Map<String, dynamic>) _getConfigFileNameAndDefault(String configType) {
    switch (configType.toLowerCase()) {
      case 'llm':
        return (_llmConfigFileName, _getDefaultLLMConfig());
      case 'vivo_ocr':
        return (_vivoOcrConfigFileName, _getDefaultVivoOcrConfig());
      case 'bocha_search':
        return ('bocha_search.json', _getDefaultBochaSearchConfig());
      case 'bocha':
        return ('bocha.json', _getDefaultBochaSearchConfig());
      default:
        return ('${configType.toLowerCase()}_dataset.json', _getDefaultDifyConfig());
    }
  }

  /// 获取默认LLM配置
  Map<String, dynamic> _getDefaultLLMConfig() {
    return {
      'model': 'qwen-plus-latest',
      'api_key': 'sk-aa328698ca6f4a7c9c0dde0b9851a772',
      'base_url': 'https://dashscope.aliyuncs.com/compatible-mode/v1/chat/completions'
    };
  }

  /// 获取默认VIVO OCR配置
  Map<String, dynamic> _getDefaultVivoOcrConfig() {
    return {
      'app_id': '2025223721',
      'secret_key': 'coirgJhVbJPuXCPj',
      'api_url': 'http://api-ai.vivo.com.cn/ocr/general_recognition',
      'enable_optimization': false
    };
  }

  /// 获取默认Dify配置
  Map<String, dynamic> _getDefaultDifyConfig() {
    return {
      "dify_dataset_api": "dataset-0ZHdF2a9wBBiCrbMUDv8oDjp",
      "dataset_name": "",
      "dify_base_url": "http://132.232.203.3/v1",
      "indexing_technique": "high_quality",
      "embedding_model": "text-embedding-v1",
      "embedding_model_provider": "tongyi",
      "retrieval_model": {
        "search_method": "hybrid_search",
        "reranking_enable": true,
        "reranking_model": {
          "reranking_provider_name": "tongyi",
          "reranking_model_name": "gte-rerank"
        },
        "top_k": 10,
        "score_threshold_enabled": false
      },
      "other_config": {
        "process_rule": {
          "rules": {
            "pre_processing_rules": [
              {"id": "remove_extra_spaces", "enabled": true},
              {"id": "remove_urls_emails", "enabled": true}
            ],
            "segmentation": {
              "separator": "###",
              "max_tokens": 500
            }
          },
          "mode": "custom"
        }
      },
      "dataset_id": ""
    };
  }

  /// 获取默认Bocha Web Search配置（开发环境测试用）
  Map<String, dynamic> _getDefaultBochaSearchConfig() {
    return {
      'api_key': 'sk-b0671ac5b43549ba9f686e824f43f49f',
      'base_url': 'https://api.bochaai.com/v1/web-search'
    };
  }

  /// 确保配置目录存在
  Future<void> _ensureConfigDirectoryExists() async {
    final configDir = Directory(path.join(_appDataDir, 'config'));
    if (!await configDir.exists()) {
      await configDir.create(recursive: true);
    }
  }

  /// 返回配置文件路径
  String returnConfigPath() {
    return path.join(_appDataDir, 'config');
  }

  /// 更新OCR配置
  Future<bool> updateOCRConfig(Map<String, dynamic> config) async {
    return await _saveJsonFile('config', _vivoOcrConfigFileName, config);
  }

  /// 更改Dify数据集配置
  Future<bool> changeDifyDatasetConfig(Map<String, dynamic> newConfig) async {
    return await _saveJsonFile('config', _difyDatasetConfigName, newConfig);
  }

  // ==================== 文档管理 ====================

  /// 保存文档索引信息
  Future<bool> saveDocumentIndex(Map<String, dynamic> indexData) async {
    return await _saveJsonFile('docs', _docIndexFileName, indexData);
  }

  /// 读取文档索引信息
  Future<Map<String, dynamic>?> readDocumentIndex() async {
    return await _readJsonFile('docs', _docIndexFileName);
  }

  /// 更新文档ID映射
  Future<bool> updateDocIdMapping(String docId, String filePath) async {
    try {
      if (!_initialized) await initialize();
      
      final mappingsFile = File(path.join(_appDataDir, 'docs', _docIdMappingsFileName));
      Map<String, dynamic> mappings = {};
      
      if (await mappingsFile.exists()) {
        final content = await mappingsFile.readAsString();
        mappings = jsonDecode(content);
      }
      
      mappings[docId] = filePath;
      await mappingsFile.writeAsString(jsonEncode(mappings));
      return true;
    } catch (e) {
      return false;
    }
  }

  /// 根据文档ID获取文件路径
  Future<String?> getFilePathByDocId(String docId) async {
    try {
      if (!_initialized) await initialize();
      
      final mappingsFile = File(path.join(_appDataDir, 'docs', _docIdMappingsFileName));
      print('mappingsFile: ${mappingsFile.path}');
      if (!await mappingsFile.exists()) {
        print('⚠️ [DEBUG] 文档ID映射文件不存在: ${mappingsFile.path}');
        return null;
      }
      
      final content = await mappingsFile.readAsString();
      final mappings = jsonDecode(content) as Map<String, dynamic>;
      final filePath = mappings[docId] as String?;
      
      if (filePath == null) {
        print('⚠️ [DEBUG] 文档ID $docId 在映射文件中未找到');
        print('🔍 [DEBUG] 映射文件中的文档ID列表: ${mappings.keys.toList()}');
      } else {
        print('✅ [DEBUG] 找到文档ID $docId 对应的文件路径: $filePath');
      }
      
      return filePath;
    } catch (e) {
      print('❌ [DEBUG] 获取文档路径时出错: $e');
      return null;
    }
  }

  /// 根据文档ID获取文档标题
  Future<String?> getDocumentTitle(String docId) async {
    try {
      if (!_initialized) await initialize();
      
      final indexData = await readDocumentIndex();
      if (indexData == null) return null;
      
      // 在文档索引中查找标题
      final documents = indexData['documents'] as List<dynamic>?;
      if (documents != null) {
        for (final doc in documents) {
          if (doc['doc_id'] == docId) {
            return doc['title'] as String?;
          }
        }
      }
      
      return null;
    } catch (e) {
      return null;
    }
  }

  /// 根据文档标题获取文档ID
  Future<String?> getDocumentIdByTitle(String title) async {
    try {
      if (!_initialized) await initialize();
      
      final indexData = await readDocumentIndex();
      if (indexData == null) return null;
      
      // 在文档索引中查找ID
      final documents = indexData['documents'] as List<dynamic>?;
      if (documents != null) {
        for (final doc in documents) {
          if (doc['title'] == title) {
            return doc['doc_id'] as String?;
          }
        }
      }
      
      return null;
    } catch (e) {
      return null;
    }
  }

  /// 根据标签获取文档ID列表
  Future<List<String>> getDocumentsByTag(String tag) async {
    try {
      if (!_initialized) await initialize();
      
      final tagData = await _readJsonFile('data', _tagFileName);
      if (tagData == null) return [];
      
      final List<String> docIds = [];
      
      // 遍历标签数据查找匹配的文档
      tagData.forEach((docId, tags) {
        if (tags is List && tags.contains(tag)) {
          docIds.add(docId);
        }
      });
      
      return docIds;
    } catch (e) {
      return [];
    }
  }

  /// 获取文档ID映射
  Future<Map<String, dynamic>> getDocIdMappings() async {
    try {
      if (!_initialized) await initialize();
      
      final mappingsFile = File(path.join(_appDataDir, 'docs', _docIdMappingsFileName));
      if (!await mappingsFile.exists()) {
        // 如果文件不存在，返回空映射
        return <String, dynamic>{};
      }
      
      final content = await mappingsFile.readAsString();
      return Map<String, dynamic>.from(jsonDecode(content));
    } catch (e) {
      return <String, dynamic>{};
    }
  }

  /// 移除文档ID映射
  Future<bool> removeDocIdMapping(String docId) async {
    try {
      if (!_initialized) await initialize();
      
      final mappingFile = File(path.join(_appDataDir, 'docs', _docIdMappingsFileName));
      if (await mappingFile.exists()) {
        final content = await mappingFile.readAsString();
        final Map<String, dynamic> mappings = jsonDecode(content);
        
        if (mappings.containsKey(docId)) {
          mappings.remove(docId);
          await mappingFile.writeAsString(jsonEncode(mappings));
          return true;
        }
      }
      return false;
    } catch (e) {
      return false;
    }
  }

  /// 更新文档ID
  Future<bool> updateDocumentId(String filePath, String tempId, String realId) async {
    try {
      if (!_initialized) await initialize();
      
      final cacheDir = Directory(path.join(_appDataDir, 'data'));
      if (!await cacheDir.exists()) return false;
      
      bool updated = false;
      await for (final entity in cacheDir.list()) {
        if (entity is File && entity.path.toLowerCase().endsWith('.json')) {
          final fileName = path.basename(entity.path);
          
          if (_isTagFile(fileName)) continue;
          
          try {
            final content = await entity.readAsString();
            final jsonData = jsonDecode(content);
            
            if (jsonData is! List) continue;
            
            List<Map<String, dynamic>> documents = List<Map<String, dynamic>>.from(
              jsonData.map((doc) => Map<String, dynamic>.from(doc))
            );
            
            bool categoryUpdated = false;
            for (int i = 0; i < documents.length; i++) {
              if (documents[i]['path'] == filePath || documents[i]['doc_id'] == tempId) {
                documents[i]['doc_id'] = realId;
                categoryUpdated = true;
                updated = true;
              }
            }
            
            if (categoryUpdated) {
              await entity.writeAsString(jsonEncode(documents));
            }
          } catch (e) {
            // 继续处理下一个文件
          }
        }
      }
      
      if (updated) {
        await updateDocIdMapping(realId, filePath);
      }
      
      return updated;
    } catch (e) {
      return false;
    }
  }

  /// 从所有分类中删除文档
  Future<bool> removeDocumentFromCategories(String docId) async {
    try {
      if (!_initialized) await initialize();
      
      final cacheDir = Directory(path.join(_appDataDir, 'data'));
      if (!await cacheDir.exists()) return false;
      
      bool documentRemoved = false;
      
      await for (final entity in cacheDir.list()) {
        if (entity is File && entity.path.endsWith('.json')) {
          final fileName = path.basename(entity.path);
          
          if (_isTagFile(fileName)) continue;
          
          try {
            final content = await entity.readAsString();
            final jsonData = jsonDecode(content);
            
            if (jsonData is! List) continue;
            
            List<Map<String, dynamic>> documents = List<Map<String, dynamic>>.from(
              jsonData.map((doc) => Map<String, dynamic>.from(doc))
            );
            
            final initialLength = documents.length;
            documents.removeWhere((doc) => doc['doc_id'] == docId);
            
            if (documents.length < initialLength) {
              await entity.writeAsString(jsonEncode(documents));
              documentRemoved = true;
            }
          } catch (e) {
            // 继续处理下一个文件
          }
        }
      }
      
      if (documentRemoved) {
        await removeDocIdMapping(docId);
      }
      
      return documentRemoved;
    } catch (e) {
      return false;
    }
  }

  /// 获取所有文档的标题和ID映射
  Future<Map<String, String>> getAllDocumentTitleIdMappings() async {
    try {
      if (!_initialized) await initialize();
      
      final Map<String, String> titleIdMap = {};
      final cacheDir = Directory(path.join(_appDataDir, 'data'));
      if (!await cacheDir.exists()) return titleIdMap;
      
      await for (final entity in cacheDir.list()) {
        if (entity is File && entity.path.endsWith('.json')) {
          final fileName = path.basename(entity.path);
          
          if (_isTagFile(fileName)) continue;
          
          try {
            final content = await entity.readAsString();
            final jsonData = jsonDecode(content);
            
            if (jsonData is! List) continue;
            
            for (final doc in jsonData) {
              final docMap = Map<String, dynamic>.from(doc);
              final docTitle = docMap['title'] as String?;
              final docId = docMap['doc_id'] as String?;
              
              if (docTitle != null && docId != null) {
                titleIdMap[docTitle] = docId;
              }
            }
          } catch (e) {
            // 继续处理下一个文件
          }
        }
      }
      
      return titleIdMap;
    } catch (e) {
      return {};
    }
  }

  /// 根据文档名称搜索相关文档（支持多个结果）
  Future<List<Map<String, String>>> searchDocumentsByTitle(String title) async {
    try {
      if (!_initialized) await initialize();
      
      final List<Map<String, String>> results = [];
      final cacheDir = Directory(path.join(_appDataDir, 'data'));
      if (!await cacheDir.exists()) return results;
      
      await for (final entity in cacheDir.list()) {
        if (entity is File && entity.path.endsWith('.json')) {
          final fileName = path.basename(entity.path);
          
          if (_isTagFile(fileName)) continue;
          
          try {
            final content = await entity.readAsString();
            final jsonData = jsonDecode(content);
            
            if (jsonData is! List) continue;
            
            final categoryName = path.basenameWithoutExtension(entity.path);
            
            for (final doc in jsonData) {
              final docMap = Map<String, dynamic>.from(doc);
              final docTitle = docMap['title'] as String?;
              final docId = docMap['doc_id'] as String?;
              
              if (docTitle != null && docId != null) {
                if (docTitle.toLowerCase().contains(title.toLowerCase()) ||
                    title.toLowerCase().contains(docTitle.toLowerCase())) {
                  results.add({
                    'title': docTitle,
                    'doc_id': docId,
                    'category': categoryName,
                  });
                }
              }
            }
          } catch (e) {
            // 继续处理下一个文件
          }
        }
      }
      
      return results;
    } catch (e) {
      return [];
    }
  }

  // ==================== 知识库管理 ====================

  /// 获取知识卡片信息
  Future<List<Map<String, dynamic>>> getKnowledgeCardInfo() async {
    try {
      if (!_initialized) await initialize();
      
      final List<Map<String, dynamic>> cardInfoList = [];
      final cacheDir = Directory(path.join(_appDataDir, 'data'));
      
      if (!await cacheDir.exists()) return cardInfoList;
      
      await for (final entity in cacheDir.list()) {
        if (entity is File && entity.path.endsWith('.json')) {
          final fileName = path.basename(entity.path);
          
          if (_isTagFile(fileName)) continue;
          
          try {
            final content = await entity.readAsString();
            final documents = jsonDecode(content) as List<dynamic>;
            
            if (documents.isNotEmpty) {
              final categoryName = path.basenameWithoutExtension(entity.path);
              cardInfoList.add({
                'category': categoryName,
                'documents': documents,
              });
            }
          } catch (e) {
            // 继续处理下一个文件
          }
        }
      }
      
      return cardInfoList;
    } catch (e) {
      return [];
    }
  }

  /// 添加文档到知识库
  Future<bool> addDocument(String filePath, String category) async {
    try {
      if (!_initialized) await initialize();
      
      await _ensureDirectoryExists('doc');
      await _ensureDirectoryExists('data');
      
      final sourceFile = File(filePath);
      if (!await sourceFile.exists()) return false;
      
      final fileName = path.basename(filePath);
      final destFile = File(path.join(_appDataDir, 'doc', fileName));
      
      if (path.dirname(filePath) != path.join(_appDataDir, 'doc')) {
        await sourceFile.copy(destFile.path);
      }
      
      final categoryFile = File(path.join(_appDataDir, 'data', '$category.json'));
      List<Map<String, dynamic>> documents = [];
      
      if (await categoryFile.exists()) {
        final content = await categoryFile.readAsString();
        documents = List<Map<String, dynamic>>.from(
          jsonDecode(content).map((doc) => Map<String, dynamic>.from(doc))
        );
      }
      
      final tempId = 'temp_${DateTime.now().millisecondsSinceEpoch}';
      final newDoc = {
        'title': path.basenameWithoutExtension(fileName),
        'path': destFile.path,
        'doc_id': tempId,
        'time': DateTime.now().toIso8601String()
      };
      
      final existingIndex = documents.indexWhere((doc) => doc['path'] == destFile.path);
      if (existingIndex != -1) {
        documents[existingIndex] = newDoc;
      } else {
        documents.add(newDoc);
      }
      
      await categoryFile.writeAsString(jsonEncode(documents));

      // 触发文档新增回调（尽力读取文本内容作为摘要）
      try {
        String contentSnippet = '';
        final ext = path.extension(destFile.path).toLowerCase();
        if (ext == '.txt' || ext == '.md') {
          try {
            final text = await destFile.readAsString();
            contentSnippet = text.length > 2000 ? text.substring(0, 2000) : text;
          } catch (_) {}
        }
        final cb = FileServe.onDocumentAdded;
        if (cb != null) {
          await cb(tempId, path.basenameWithoutExtension(fileName), contentSnippet);
        }
      } catch (_) {}

      return true;
    } catch (e) {
      return false;
    }
  }

  /// 文件重命名
  Future<(List<Map<String, dynamic>>, int)?> renameFile(String category, String newname, String filePath) async {
    try {
      final currentFile = File(filePath);
      final fileExtension = path.extension(filePath);
      final directory = path.dirname(filePath);
      final newPath = path.join(directory, newname + fileExtension);
      
      await currentFile.rename(newPath);
      
      await _ensureDirectoryExists('data');
      
      final categoryFile = File(path.join(_appDataDir, 'data', '$category.json'));
      List<Map<String, dynamic>> documents = [];
      
      if (await categoryFile.exists()) {
        final content = await categoryFile.readAsString();
        documents = List<Map<String, dynamic>>.from(
          jsonDecode(content).map((doc) => Map<String, dynamic>.from(doc))
        );
      }
      
      final existingIndex = documents.indexWhere((doc) => doc['path'] == filePath);
      if (existingIndex != -1) {
        documents[existingIndex]['title'] = newname + fileExtension;
        documents[existingIndex]['path'] = newPath;
        await categoryFile.writeAsString(jsonEncode(documents));
      }
      
      return (documents, existingIndex);
    } catch (e) {
      return null;
    }
  }

  // ==================== 分类管理 ====================

  /// 获取所有分类标签
  Future<List<String>> getCategories() async {
    try {
      if (!_initialized) await initialize();
      
      final cacheDir = Directory(path.join(_appDataDir, 'data'));
      if (!await cacheDir.exists()) {
        await cacheDir.create(recursive: true);
        return _defaultCategories;
      }
      
      final files = await cacheDir.list().toList();
      final categories = <String>[];
      
      for (var file in files) {
        if (file is File && file.path.toLowerCase().endsWith('.json')) {
          final fileName = path.basename(file.path);
          
          if (_isTagFile(fileName)) continue;
          
          final categoryName = fileName.substring(0, fileName.length - 5);
          categories.add(categoryName);
        }
      }
      
      if (categories.isEmpty) return _defaultCategories;
      
      categories.sort();
      return categories;
    } catch (e) {
      return _defaultCategories;
    }
  }

  /// 添加新分类
  Future<bool> addCategory(String categoryName) async {
    try {
      if (!_initialized) await initialize();
      
      await _ensureDirectoryExists('data');
      
      final categoryFile = File(path.join(_appDataDir, 'data', '$categoryName.json'));
      if (!await categoryFile.exists()) {
        await categoryFile.writeAsString(jsonEncode([]));
      }
      
      return true;
    } catch (e) {
      return false;
    }
  }

  // ==================== 临时文件管理 ====================

  /// 临时文件存储
  Future<String> saveTempFile(String content, {String? filename}) async {
    try {
      if (!_initialized) await initialize();
      
      final tempFileName = filename ?? '${DateTime.now().millisecondsSinceEpoch}.txt';
      final tempFile = File(path.join(_appDataDir, 'temp', tempFileName));
      
      await tempFile.writeAsString(content);
      return tempFile.path;
    } catch (e) {
      rethrow;
    }
  }

  /// 保存图片到临时目录
  Future<String> saveTempImage(List<int> imageBytes, String extension) async {
    try {
      if (!_initialized) await initialize();
      
      final tempFileName = '${DateTime.now().millisecondsSinceEpoch}.$extension';
      final tempFile = File(path.join(_appDataDir, 'temp', tempFileName));
      
      await tempFile.writeAsBytes(imageBytes);
      return tempFile.path;
    } catch (e) {
      rethrow;
    }
  }

  /// 清理临时文件
  Future<void> cleanTempFiles() async {
    try {
      if (!_initialized) await initialize();
      
      final tempDir = Directory(path.join(_appDataDir, 'temp'));
      if (await tempDir.exists()) {
        await for (final entity in tempDir.list()) {
          await entity.delete(recursive: true);
        }
      }
    } catch (e) {
      // 清理失败不影响应用运行
    }
  }

  // ==================== 用户头像管理 ====================

  /// 保存用户头像
  Future<bool> saveUserAvatar(List<int> imageBytes, String extension) async {
    try {
      if (!_initialized) await initialize();
      
      await _ensureDirectoryExists('config');
      
      final avatarFile = File(path.join(_appDataDir, 'config', '$_userPicPrefix.$extension'));
      await avatarFile.writeAsBytes(imageBytes);
      
      return true;
    } catch (e) {
      return false;
    }
  }

  /// 获取用户头像路径
  Future<String?> getUserAvatarPath() async {
    try {
      if (!_initialized) await initialize();
      
      final configDir = Directory(path.join(_appDataDir, 'config'));
      if (!await configDir.exists()) return null;
      
      final extensions = ['jpg', 'jpeg', 'png', 'gif'];
      for (final ext in extensions) {
        final avatarFile = File(path.join(configDir.path, '$_userPicPrefix.$ext'));
        if (await avatarFile.exists()) {
          return avatarFile.path;
        }
      }
      
      return null;
    } catch (e) {
      return null;
    }
  }

  /// 删除用户头像
  Future<bool> deleteUserAvatar() async {
    try {
      if (!_initialized) await initialize();
      
      final configDir = Directory(path.join(_appDataDir, 'config'));
      if (!await configDir.exists()) return false;
      
      final extensions = ['jpg', 'jpeg', 'png', 'gif'];
      bool deleted = false;
      
      for (final ext in extensions) {
        final avatarFile = File(path.join(configDir.path, '$_userPicPrefix.$ext'));
        if (await avatarFile.exists()) {
          await avatarFile.delete();
          deleted = true;
        }
      }
      
      return deleted;
    } catch (e) {
      return false;
    }
  }

  // ==================== 标签管理 ====================

  /// 更新分类的标签统计
  Future<bool> updateCategoryTagStats(String category, List<String> tags) async {
    try {
      if (!_initialized) await initialize();
      
      final categoryTagFile = File(path.join(_appDataDir, 'data', '${category}_tags.json'));
      Map<String, int> tagStats = {};
      
      if (await categoryTagFile.exists()) {
        final content = await categoryTagFile.readAsString();
        final jsonData = jsonDecode(content) as Map<String, dynamic>;
        
        for (final entry in jsonData.entries) {
          tagStats[entry.key] = entry.value as int;
        }
      }
      
      for (final tag in tags) {
        tagStats[tag] = (tagStats[tag] ?? 0) + 1;
      }
      
      await categoryTagFile.writeAsString(jsonEncode(tagStats));
      return true;
    } catch (e) {
      return false;
    }
  }

  /// 获取分类的热门标签（前N个）
  Future<List<Map<String, dynamic>>> getCategoryTopTags(String category, {int limit = 5}) async {
    try {
      if (!_initialized) await initialize();
      
      final categoryTagFile = File(path.join(_appDataDir, 'data', '${category}_tags.json'));
      if (!await categoryTagFile.exists()) return [];
      
      final content = await categoryTagFile.readAsString();
      final Map<String, dynamic> tagStats = jsonDecode(content);
      
      final sortedTags = <Map<String, dynamic>>[];
      for (final entry in tagStats.entries) {
        sortedTags.add({
          'tag': entry.key,
          'count': entry.value as int,
        });
      }
      
      sortedTags.sort((a, b) => (b['count'] as int).compareTo(a['count'] as int));
      return sortedTags.take(limit).toList();
    } catch (e) {
      return [];
    }
  }

  /// 获取分类的所有标签
  Future<List<Map<String, dynamic>>> getCategoryAllTags(String category) async {
    try {
      if (!_initialized) await initialize();
      
      final categoryTagFile = File(path.join(_appDataDir, 'data', '${category}_tags.json'));
      if (!await categoryTagFile.exists()) return [];
      
      final content = await categoryTagFile.readAsString();
      final Map<String, dynamic> tagStats = jsonDecode(content);
      
      final allTags = <Map<String, dynamic>>[];
      for (final entry in tagStats.entries) {
        allTags.add({
          'tag': entry.key,
          'count': entry.value as int,
        });
      }
      
      allTags.sort((a, b) => (b['count'] as int).compareTo(a['count'] as int));
      return allTags;
    } catch (e) {
      return [];
    }
  }

  /// 根据标签获取分类下的相关文档
  Future<List<Map<String, dynamic>>> getDocumentsByTagInCategory(String category, String tag) async {
    try {
      if (!_initialized) await initialize();
      
      final categoryFile = File(path.join(_appDataDir, 'data', '$category.json'));
      if (!await categoryFile.exists()) return [];
      
      final content = await categoryFile.readAsString();
      final List<dynamic> documents = jsonDecode(content);
      
      final matchedDocs = <Map<String, dynamic>>[];
      
      for (final doc in documents) {
        final docMap = Map<String, dynamic>.from(doc);
        final tags = docMap['tags'] as List<dynamic>?;
        
        if (tags != null && tags.contains(tag)) {
          matchedDocs.add(docMap);
        }
      }
      
      return matchedDocs;
    } catch (e) {
      return [];
    }
  }

  /// 获取所有分类的标签概览
  Future<Map<String, List<Map<String, dynamic>>>> getAllCategoriesTagsSummary({int limitPerCategory = 3}) async {
    try {
      if (!_initialized) await initialize();
      
      final Map<String, List<Map<String, dynamic>>> summary = {};
      final categories = await getCategories();
      
      for (final category in categories) {
        final topTags = await getCategoryTopTags(category, limit: limitPerCategory);
        summary[category] = topTags;
      }

      return summary;
    } catch (e) {
      return {};
    }
  }

  /// 清理空的分类标签文件
  Future<void> cleanEmptyCategoryTagFiles() async {
    try {
      if (!_initialized) await initialize();
      
      final cacheDir = Directory(path.join(_appDataDir, 'data'));
      
      await for (final entity in cacheDir.list()) {
        if (entity is File && entity.path.endsWith('_tags.json')) {
          try {
            final content = await entity.readAsString();
            final Map<String, dynamic> tagStats = jsonDecode(content);
            
            if (tagStats.isEmpty) {
              await entity.delete();
            }
          } catch (e) {
            // 继续处理下一个文件
          }
        }
      }
    } catch (e) {
      // 清理失败不影响应用运行
    }
  }

  /// 获取全局标签数据（tag.json）
  Future<Map<String, List<String>>> getGlobalTags() async {
    try {
      if (!_initialized) await initialize();
      
      final tagFile = File(path.join(_appDataDir, 'data', _tagFileName));
      if (!await tagFile.exists()) return {};

      final content = await tagFile.readAsString();
      final jsonData = jsonDecode(content) as Map<String, dynamic>;
      
      final Map<String, List<String>> tagData = {};
      for (final entry in jsonData.entries) {
        tagData[entry.key] = List<String>.from(entry.value as List);
      }
      
      return tagData;
    } catch (e) {
      return {};
    }
  }

  /// 获取所有标签名称列表
  Future<List<String>> getAllTagNames() async {
    try {
      final globalTags = await getGlobalTags();
      final tagNames = globalTags.keys.toList();
      tagNames.sort();
      return tagNames;
    } catch (e) {
      return [];
    }
  }

  /// 获取标签统计信息（按文档数量排序）
  Future<List<Map<String, dynamic>>> getTagStatistics() async {
    try {
      final globalTags = await getGlobalTags();
      final tagStats = <Map<String, dynamic>>[];
      
      for (final entry in globalTags.entries) {
        tagStats.add({
          'tag': entry.key,
          'documentCount': entry.value.length,
          'documents': entry.value,
        });
      }
      
      tagStats.sort((a, b) => (b['documentCount'] as int).compareTo(a['documentCount'] as int));
      return tagStats;
    } catch (e) {
      return [];
    }
  }

  /// 搜索标签（模糊匹配）
  Future<List<String>> searchTags(String query) async {
    try {
      final allTags = await getAllTagNames();
      return allTags
          .where((tag) => tag.toLowerCase().contains(query.toLowerCase()))
          .toList();
    } catch (e) {
      return [];
    }
  }

  // ==================== 阅读位置管理 ====================

  /// 保存文档阅读位置
  Future<bool> saveDocumentReadingPosition(String docId, int currentPage, int totalPages) async {
    try {
      if (!_initialized) await initialize();
      
      final positionFile = File(path.join(_appDataDir, 'data', _readingPositionsFileName));
      Map<String, dynamic> positions = {};
      
      if (await positionFile.exists()) {
        final content = await positionFile.readAsString();
        positions = jsonDecode(content);
      }
      
      positions[docId] = {
        'current_page': currentPage,
        'total_pages': totalPages,
        'last_read_time': DateTime.now().toIso8601String(),
      };
      
      await positionFile.writeAsString(jsonEncode(positions));
      return true;
    } catch (e) {
      return false;
    }
  }

  /// 获取文档阅读位置
  Future<Map<String, dynamic>?> getDocumentReadingPosition(String docId) async {
    try {
      if (!_initialized) await initialize();
      
      final positionFile = File(path.join(_appDataDir, 'data', _readingPositionsFileName));
      if (!await positionFile.exists()) return null;
      
      final content = await positionFile.readAsString();
      final Map<String, dynamic> positions = jsonDecode(content);
      
      if (positions.containsKey(docId)) {
        return Map<String, dynamic>.from(positions[docId]);
      }
      
      return null;
    } catch (e) {
      return null;
    }
  }

  /// 删除文档阅读位置
  Future<bool> removeDocumentReadingPosition(String docId) async {
    try {
      if (!_initialized) await initialize();
      
      final positionFile = File(path.join(_appDataDir, 'data', _readingPositionsFileName));
      if (!await positionFile.exists()) return true;
      
      final content = await positionFile.readAsString();
      final Map<String, dynamic> positions = jsonDecode(content);
      
      if (positions.containsKey(docId)) {
        positions.remove(docId);
        await positionFile.writeAsString(jsonEncode(positions));
      }
      
      return true;
    } catch (e) {
      return false;
    }
  }

  /// 获取所有文档的阅读位置统计
  Future<Map<String, dynamic>> getReadingPositionStats() async {
    try {
      if (!_initialized) await initialize();
      
      final positionFile = File(path.join(_appDataDir, 'data', _readingPositionsFileName));
      if (!await positionFile.exists()) return {};
      
      final content = await positionFile.readAsString();
      final Map<String, dynamic> positions = jsonDecode(content);
      
      final stats = <String, dynamic>{};
      for (final entry in positions.entries) {
        final docId = entry.key;
        final position = entry.value;
        final currentPage = position['current_page'] ?? 0;
        final totalPages = position['total_pages'] ?? 1;
        final progress = totalPages > 0 ? (currentPage / totalPages * 100).round() : 0;
        
        stats[docId] = {
          'current_page': currentPage,
          'total_pages': totalPages,
          'progress_percent': progress,
          'last_read_time': position['last_read_time'],
        };
      }
      
      return stats;
    } catch (e) {
      return {};
    }
  }

  // ==================== 消息池管理 ====================

  /// 分享消息到消息池（工具调用方式）
  Future<String> shareMessage({required String content, required String name}) async {
    try {
      if (!_initialized) await initialize();
      
      final now = DateTime.now();
      final timeFormatter = DateFormat('yyyy-MM-dd-HH:mm');
      
      final message = {
        'role': 'assistant',
        'name': name,
        'content': content,
        'time': timeFormatter.format(now),
      };
      
      final success = await _saveMessageToPool(message);
      
      if (success) {
        // 触发回调：有新消息写入时通知上层（例如AgentManager）
        try {
          final cb = FileServe.onMessageShared;
          if (cb != null) {
            await cb();
          }
        } catch (_) {}
        return '消息已成功分享到消息池，其他助手可以看到这条信息。';
      } else {
        return '分享消息失败，请稍后重试。';
      }
    } catch (e) {
      return '分享消息时发生错误: $e';
    }
  }

  /// 保存消息到消息池（内部方法）
  Future<bool> _saveMessageToPool(Map<String, dynamic> message) async {
    try {
      if (!_initialized) await initialize();
      
      await _ensureDirectoryExists('chat');
      
      final messagesPoolFile = File(path.join(_appDataDir, 'chat', _messagesPoolFileName));
      List<Map<String, dynamic>> messages = [];
      
      if (await messagesPoolFile.exists()) {
        // 文件存在：读取并进行去重检查
        try {
          final content = await messagesPoolFile.readAsString();
          messages = List<Map<String, dynamic>>.from(jsonDecode(content));
        } catch (_) {
          // 文件损坏或解析失败时，重置为空列表
          messages = [];
        }
        
        final newName = message['name']?.toString() ?? '';
        final newContent = message['content']?.toString() ?? '';
        final isDuplicate = messages.any((m) =>
          (m['name']?.toString() ?? '') == newName &&
          (m['content']?.toString() ?? '') == newContent
        );
        
        // 如果已存在相同 name+content 的消息，则不再添加
        if (isDuplicate) {
          return true;
        }
        
        messages.add(message);
      } else {
        // 文件不存在：创建并写入第一条消息
        messages = [message];
      }
      
      // 限制消息池大小，保留最近的100条消息
      if (messages.length > 100) {
        messages = messages.sublist(messages.length - 100);
      }
      
      await messagesPoolFile.writeAsString(jsonEncode(messages));
      return true;
    } catch (e) {
      return false;
    }
  }

  /// 获取消息池内容
  Future<List<Map<String, dynamic>>> getMessagesPool() async {
    try {
      if (!_initialized) await initialize();
      
      final messagesPoolFile = File(path.join(_appDataDir, 'chat', _messagesPoolFileName));
      if (!await messagesPoolFile.exists()) return [];
      
      final content = await messagesPoolFile.readAsString();
      final messages = List<Map<String, dynamic>>.from(jsonDecode(content));
      
      // 返回最近的10条消息
      if (messages.length > 10) {
        return messages.sublist(messages.length - 10);
      }
      
      return messages;
    } catch (e) {
      return [];
    }
  }

  /// 从消息池加载消息（保留兼容性）
  Future<List<Map<String, dynamic>>> loadMessagesPool() async {
    return await getMessagesPool();
  }

  /// 清空消息池
  Future<bool> clearMessagesPool() async {
    try {
      if (!_initialized) await initialize();
      
      final messagesPoolFile = File(path.join(_appDataDir, 'chat', _messagesPoolFileName));
      if (!await messagesPoolFile.exists()) return true;
      
      await messagesPoolFile.delete();
      return true;
    } catch (e) {
      return false;
    }
  }

  // ==================== 笔记管理 ====================

  /// 获取notes目录下的所有笔记文件
  Future<List<Map<String, dynamic>>> getNotesList() async {
    try {
      if (!_initialized) await initialize();
      
      final notesDir = Directory(path.join(_appDataDir, 'notes'));
      if (!await notesDir.exists()) {
        await notesDir.create(recursive: true);
        return [];
      }

      final notes = <Map<String, dynamic>>[];
      
      await for (final entity in notesDir.list()) {
        if (entity is File && entity.path.endsWith('.md')) {
          try {
            final content = await entity.readAsString();
            final stat = await entity.stat();
            
            String title = path.basenameWithoutExtension(entity.path);
            final lines = content.split('\n');
            if (lines.isNotEmpty && lines[0].startsWith('# ')) {
              title = lines[0].substring(2).trim();
            }

            notes.add({
              'fileName': path.basename(entity.path),
              'filePath': entity.path,
              'title': title,
              'content': content,
              'modifiedTime': stat.modified.toIso8601String(),
              'size': stat.size,
            });
          } catch (e) {
            print('读取笔记文件失败: ${entity.path}, 错误: $e');
          }
        }
      }

      notes.sort((a, b) => 
        DateTime.parse(b['modifiedTime']).compareTo(DateTime.parse(a['modifiedTime'])));

      return notes;
    } catch (e) {
      print('获取笔记列表失败: $e');
      return [];
    }
  }

  /// 保存笔记内容
  Future<bool> saveNote(String title, String content, {String? existingFilePath}) async {
    try {
      if (!_initialized) await initialize();
      
      final notesDir = Directory(path.join(_appDataDir, 'notes'));
      if (!await notesDir.exists()) {
        await notesDir.create(recursive: true);
      }

      String fileName;
      if (existingFilePath != null) {
        fileName = path.basename(existingFilePath);
      } else {
        fileName = '${title.trim()}.md';
      }

      final file = File(path.join(notesDir.path, fileName));
      final markdownContent = '# ${title.trim()}\n\n$content';
      
      await file.writeAsString(markdownContent);
      return true;
    } catch (e) {
      print('保存笔记失败: $e');
      return false;
    }
  }

  /// 删除笔记
  Future<bool> deleteNote(String filePath) async {
    try {
      final file = File(filePath);
      if (await file.exists()) {
        await file.delete();
        return true;
      }
      return false;
    } catch (e) {
      print('删除笔记失败: $e');
      return false;
    }
  }

  /// 读取笔记内容
  Future<Map<String, dynamic>?> readNote(String filePath) async {
    try {
      final file = File(filePath);
      if (!await file.exists()) return null;

      final content = await file.readAsString();
      final stat = await file.stat();
      
      String title = path.basenameWithoutExtension(filePath);
      String noteContent = content;
      
      final lines = content.split('\n');
      if (lines.isNotEmpty && lines[0].startsWith('# ')) {
        title = lines[0].substring(2).trim();
        noteContent = lines.skip(1).join('\n').trim();
      }

      return {
        'title': title,
        'content': noteContent,
        'rawContent': content,
        'modifiedTime': stat.modified.toIso8601String(),
        'size': stat.size,
      };
    } catch (e) {
      print('读取笔记失败: $e');
      return null;
    }
  }

  // ==================== 私有通用辅助方法 ====================

  /// 保存JSON文件的通用方法
  Future<bool> _saveJsonFile(String subDir, String fileName, Map<String, dynamic> data) async {
    try {
      if (!_initialized) await initialize();
      
      await _ensureDirectoryExists(subDir);
      
      final file = File(path.join(_appDataDir, subDir, fileName));
      await file.writeAsString(jsonEncode(data));
      return true;
    } catch (e) {
      return false;
    }
  }

  /// 读取JSON文件的通用方法
  Future<Map<String, dynamic>?> _readJsonFile(String subDir, String fileName) async {
    try {
      if (!_initialized) await initialize();
      
      final file = File(path.join(_appDataDir, subDir, fileName));
      if (await file.exists()) {
        final content = await file.readAsString();
        return jsonDecode(content) as Map<String, dynamic>;
      }
      return null;
    } catch (e) {
      return null;
    }
  }

  /// 确保目录存在
  Future<void> _ensureDirectoryExists(String subDir) async {
    final directory = Directory(path.join(_appDataDir, subDir));
    if (!await directory.exists()) {
      await directory.create(recursive: true);
    }
  }

  /// 判断是否为标签文件
  bool _isTagFile(String fileName) {
    return fileName.endsWith('_tags.json') || 
           fileName == _tagFileName || 
           fileName == _readingPositionsFileName ||
           fileName == _messagesPoolFileName;
  }

  // ==================== 遗留方法（保持兼容性） ====================

  /// 获取Android/obb目录路径
  Future<String?> getAndroidObbPath() async {
    if (!Platform.isAndroid) return null;
    
    try {
      final externalDir = await getExternalStorageDirectory();
      if (externalDir != null) {
        final androidDataPath = externalDir.path;
        final appDirIndex = androidDataPath.indexOf('/Android/data/');
        // 这里可以继续实现obb路径逻辑，但当前实现为空
      }
    } catch (e) {
      // 获取失败
    }
    return null;
  }
}

/// Dify配置类
class DifyConfig {
  Map<String, dynamic> config = {};
  
  Future<void> readConfig() async {
    final fileServe = FileServe();
    await fileServe.initialize();
    config = await fileServe.getConfig('Dify');
  }
  
  String returnConfigPath() {
    final fileServe = FileServe();
    return fileServe.returnConfigPath();
  }
} 